#include "TcpConnect.h"

using std::cout;
using std::endl;

TcpConnect::TcpConnect(int cltFd)
    : _cltFd{cltFd}, _io{cltFd}
{
}

TcpConnect::TcpConnect(const TcpConnect &rhs)
    : _cltFd{rhs._cltFd}, _io{_cltFd}
{
}

std::string TcpConnect::receive()
{
    char buf[65535];
    _io.readLine(buf, sizeof(buf));
    return buf;
}

InetAddress TcpConnect::getLocalAddress() const
{
    sockaddr_in addr{};
    socklen_t len = sizeof(addr);
    int ret = getsockname(_cltFd, (sockaddr *)&addr, &len);
    if (ret < 0)
    {
        perror("getsockname");
        exit(-1);
    }
    return addr;
}

InetAddress TcpConnect::getPeerAddress() const
{
    sockaddr_in addr{};
    socklen_t len = sizeof(addr);
    int ret = getpeername(_cltFd, (sockaddr *)&addr, &len);
    if (ret < 0)
    {
        perror("getpeername");
        exit(-1);
    }
    return addr;
}

void TcpConnect::send(const char *buf)
{
    _io.writen(buf, strlen(buf));
}

const std::string TcpConnect::toString() const
{
    InetAddress ser = getLocalAddress();
    InetAddress clt = getPeerAddress();
    std::stringstream oss;
    oss << ser.ip() << ": "
        << ser.port() << " ----> "
        << clt.ip() << ": "
        << clt.port();

    return oss.str();
}

void TcpConnect::shutdown()
{
    close(_cltFd);
}
void TcpConnect::setClosedCallback(callback cb)
{
    _closedCallback = std::move(cb);
}

void TcpConnect::setMessageCallback(callback cb)
{
    _handleMessageCallback = std::move(cb);
}

void TcpConnect::setConnectCallback(callback cb)
{
    _connectCallback = std::move(cb);
}

void TcpConnect::handleClosed()
{
    _closedCallback(shared_from_this());
}

void TcpConnect::handleMessage()
{
    _handleMessageCallback(shared_from_this());
}

void TcpConnect::handleConnect()
{
    _connectCallback(shared_from_this());
}